Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate LiveContainerUI to SwiftUI, Support for Multiple LiveContainer, SideJIT/JITStreamer Support, Better Open in App Support, Impelement #112 #153

Merged
merged 38 commits into from
Sep 20, 2024

Conversation

hugeBlack
Copy link
Collaborator

Switch UI to SwiftUI

I migrated most of features to an AltStore-like UI written in SwiftUI.

LiveContainerSwiftUI looks like this:
IMG_4706

Support for Multiple LiveContainer

Free development accounts can install 3 apps, so now we can install 1 SideStore and 2 LiveContainers, so people can run 2 apps at the same time. App and their data, Keychains and most NSUserDefaults can be shared between these 2 LiveContainers. If user open a app via URL Scheme or from My Apps screen, the LiveContainer that last ran that app will be switched to.

App's data and tweaks are stored in SideStore's or AltStore's app group. If a Shared App is launched, its data will be temporarily moved to the LiveContainer's document folder to prevent crash in background because of holding a file lock in the App Group folder. It data will be moved back in last launch of LiveContainer.

Apps can't be modified when in Shared state. The second LiveContainer cannot install or manage apps.

NSUserDefaults are handled differently. Since it won't accept plists that moved to Library/Preferences after app launch, we have to manually read the plists and set it in NSUserDefaults. This solves #149

Better Open in App Support

It turns out that some apps don't rely on URL Schemes and use Universal Links instead. So in the new LiveContainerSwiftUI, the web page's apple-app-site-association will be checked and we will launch apps based on it. Then, a NSUserActivity will be created with these URLs and passed to UIActivityContinuationManager, so apps will open these URLs they support.

Impelement #112

Flutter apps share the bundle name of Runner.app, so I use bundle identifier as app bundle's name during install to avoid conflicts. Also, users can select which bundle to replace if there are multiple bundles with the same bundle identifier.

@hugeBlack
Copy link
Collaborator Author

Users can now mark app as JIT needed and configure SideJITServer inside LiveContainer, so that apps can be launched with JIT more easily.

Also solved some weird permission issue by modifying the second one's main executable's UUID.

@hugeBlack hugeBlack changed the title Migrate LiveContainerUI to SwiftUI, Support for Multiple LiveContainer, Better Open in App Support, Impelement #112 Migrate LiveContainerUI to SwiftUI, Support for Multiple LiveContainer, SideJIT/JITStreamer Support, Better Open in App Support, Impelement #112 Sep 10, 2024
@khanhduytran0
Copy link
Owner

This is huge, at this point I may consider adding you to collaborator, thanks a lot.
While you’re at it, you may also implement #131

@hugeBlack
Copy link
Collaborator Author

Thank you for your appreciation! I've now completed the implementation of #131. Users can now triple tap the app counter under the app list, pass the authorization and view hidden app and hide apps.

By the way, I implemented the App Clip generation, but I didn't figure out how you made SFSafariViewController to open data: urls and it will crash the app because it wants a http or https URL. So I opt for starting a local server that serves that MDM config instead.

Copy link

@ilian ilian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for your work 💪 This is a big PR 🤯

I didn't review the code but I wanted to give some feedback as a big fan of LiveContainer:

  • I found that the Open data folder option when long-pressing an app is missing. I found this feature quite useful to quickly open the files app and examine the contents. It would be nice if this was kept in this PR.
  • After upgrading the from d074394 (on main) to 901282b, running an app causes its Library/Preferences directory to be filled with preferences of other installed apps. I tried to delete plist files that are not relevant to the given app but they re-appear after running the app again. Is this expected? I didn't check if this happens also for new users who did not perform an upgrade in-place.
  • Each app's UUID is now less visible. I now have to hold the app and click on Change Data Folder to view the name of the data folder which is usually equal to the UUID if not yet renamed. It would be nice if the UUID was visible either directly under the app's name in the list (as before) or maybe show it under the app's context menu?
  • The app list does not appear to have the same style as you showed in the screenshot in the description of your PR. I am running 901282b on iOS 17.6.1. I triggered a CI build for this commit by enabling GitHub Actions for my fork. You can download the IPA under artifacts using this link. You can find a screenshot below:
    image
  • After installing a new app, pressing on Run results in the app closing and opening twice, eventually returning to the main LiveContainer app. This only seem to happen after a fresh install of the app. I am able to run the app perfectly fine after that though, even when restarting LiveContainer.

I hope that helps!

@khanhduytran0
Copy link
Owner

but I didn't figure out how you made SFSafariViewController to open data: urls and it will crash the app because it wants a http or https URL.

Here’s how I bypassed it:

@implementation NSURL(hack)
- (BOOL)safari_isHTTPFamilyURL {
// Screw it, Apple
return YES;
}
@end

Furthermore, generating self-signed shortcut instead is possible too, see https://github.com/0xilis/SelfSignedShortcutDemo

@hugeBlack
Copy link
Collaborator Author

hugeBlack commented Sep 13, 2024

Thank you for your feedback! @ilian

  • I did forget about the open data folder button. I'll add it back soon.
  • It seems that the missing of Assets.car is causing the weird looking UI and missing UUID since the text color turned black and blended into the background. I presume that something went wrong when building with GitHub Actions.
  • Since apps' preferences are now also stored separately and we have no way to know which plist belongs to which app, all preferences will be moved to the the preferences folder of the first app launched after the update, but should not happen after. I guess the issuse you encountered is caused by killing LiveContainer from the app switcher and remove all plists before LiveContainer's next launch. Preferences are moved back upon next launch, so I think LiveContainer just moved back all plists back that it read before you launch the app. So you may try to remove these plists after you relaunch LiveContainer and such issue should not happen again.
  • I can't reproduce the issue that app crash after install. I tried apps like Apollo, Youtube, EeveeSpotify, iTorrent, Aidoku etc. and none of them crashed after install. So may I know which apps crash after install? (I tested on a JB iOS 17.6.1 iPad so maybe there's a difference?)
  • OK, there's something wrong with CodeSigning for the newly installed apps, I'll look into this soon.

hugeBlack and others added 2 commits September 13, 2024 14:10
* Update Makefile

* Update Makefile

* Update Makefile

* move to main make file
@hugeBlack
Copy link
Collaborator Author

I added the "Open Data Folder" button back, change the AppClip creation method back to data: url, fixed GitHub Actions building issue and probably fixed the issue that apps crash after install issue.

You can download the new version here.

Furthermore, generating self-signed shortcut instead is possible too, see https://github.com/0xilis/SelfSignedShortcutDemo

I see. However users have to enroll a self-signed root CA to install a shortcut, which may raise some security concerns. What't more, users still have to manually select an icon before adding the generated shortcut to Home Screen, or is there a way to automate this procedure?

@ilian
Copy link

ilian commented Sep 13, 2024

@hugeBlack Thank you for your responses and for fixing things so quickly 🚀

I was able to modify preferences in Library/Preferences and have the app read the new preferences 👍

all preferences will be moved to the the preferences folder of the first app launched after the update, but should not happen after

For each app, I deleted all plists that belong to other apps, click on Run, kill the app. Sometimes the plists came back and I had to perform this operation twice. When running the same app multiple times, I do not see any unrelated plists for that particular app. Once I start using multiple apps instead of a single one, I see unrelated plists under Library/Preferences again. It seems that LiveContainer is still keeping some internal state from previous runs instead of exclusively using the app's Library/Preferences directory as the source of truth. Are you able to reproduce this issue or do you need more detailed steps to reproduce this issue?

probably fixed the issue that apps crash after install issue

Unfortunately, I still get the same issue after installing a new app and clicking on Run. After it crashes once, I am able to run it multiple times just fine.

Regarding UX, maybe it makes more sense to have the Uninstall item in the context menu at the bottom to be consistent with other apps such as Files. Maybe it also makes sense to move Open Data Folder to the top since I think it's more commonly used than the current item at the top (Mark as JIT Needed).

For context, I am running the app with version cd2c019.

@hugeBlack
Copy link
Collaborator Author

hugeBlack commented Sep 15, 2024

@ilian thank for your feedback again! 👍

This commit hopefully fixed the issue that app crash once after installation (I tested on 4 devices ranging from iOS 15 to iOS 18, and they all worked fine).

As for the mixed preference issue, after some testing, I found that the behavior of cfprefsd which manages NSUserDefaults is somewhat unpredictable and it is hard to find a stable way to dump and load preferences. So I will forgo this feature for now since I don't want to waste too much time on it and it is rather stable in spite of the mixed preference files.

What't more, I solved the issue (like #68 #123 #142) that file pickers cannot select files. The cause of this issue is that custom UTTypes created by guest apps have not been registered in iOS so they will become nil, which made file pickers unable to select file of any type.

I intercept the call to -[UIDocumentPickerViewController initForExportingURLs:asCopy:] and change to initForExportingURLs to @[UTTypeItem, UTTypeFolder] so any file or folder can be chosen. Tested on Delta, UTM, iTorrent.

However, it seems that files must be copied in order to be imported, and the app must use UIDocumentPickerViewController, not UIDocumentBrowserViewController in order to get files copied. I presume this is an issue with entitlements of guest apps, since there are similar issues found in iTorrent and UTM caused by faulty sign tools(utmapp/UTM#5491). But this may be impossible to solve based on how JIT-Less mode worked.

Also, buttons in the app manage menu is rearranged based on your suggestion.

@Wei-Winter
Copy link

I found that Infuse still cannot mount local folders. Specifically, when navigating to a folder, the “Open” button cannot be clicked. If you click on a file, it will show a file error.

@hugeBlack
Copy link
Collaborator Author

hugeBlack commented Sep 17, 2024

@Wei-Winter Thank for your feedback!

I think that the issue with Infuse should be fixed in the latest commit. You may download and have a try. Be sure to enable 'fix file picker' setting in app settings. Do note that files will be copied to the Inbox of guest app.

@Wei-Winter
Copy link

Thank you for your submission! It is running well now👍

@hugeBlack
Copy link
Collaborator Author

Localization is now supported. You can add a language in LiveContainerSwiftUI project and add your translation in Localizable.xcstrings.

@Wei-Winter
Copy link

Can this app be supported on LiveContainer? I can't even install it on SideStore.
#134

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants